package com.ocm.core.dao.jpa;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManagerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.ocm.core.dao.ClassDefDao;
import com.ocm.core.domain.ClassDefinition;
import com.ocm.core.domain.ClassDefinitionType;

@Repository("classDefDao")
public class JpaClassDefDao extends JpaGenericDao<ClassDefinition> implements ClassDefDao {

   @Autowired
   public JpaClassDefDao(@Qualifier("ocmEntityManagerFactory")EntityManagerFactory entityManagerFactory) {
      super(ClassDefinition.class);
      super.setEntityManagerFactory(entityManagerFactory);
   }

   @SuppressWarnings("unchecked")
   public List<ClassDefinition> findAll() {
      List<ClassDefinition> classDefs = this.getJpaTemplate().findByNamedQuery(ClassDefinition.FIND_ALL);
      return classDefs;
   }

   @SuppressWarnings("unchecked")
   public ClassDefinition findName(Long storageId,String name) {
      Map<String, Object> paras = new HashMap<String, Object>();
      paras.put(ClassDefinition.NAME_PARA, name);
      paras.put(ClassDefinition.ID_PARA, storageId);
      List<ClassDefinition> classDefs = this.getJpaTemplate().findByNamedQueryAndNamedParams(ClassDefinition.FIND_NAME, paras);
      if (classDefs.size() > 0){
         return classDefs.get(0);
      }
      return null;
   }

   @SuppressWarnings("unchecked")
   public List<ClassDefinition> findByParentId(Long parentId, ClassDefinitionType... types) {
      List<ClassDefinition> classDefs = null;
      Map<String, Object> paras = new HashMap<String, Object>();
      paras.put(ClassDefinition.PARENT_ID_PARA, parentId);
      if (types != null && types.length > 0){
         paras.put(ClassDefinition.TYPES_PARA, new ArrayList<ClassDefinitionType>(Arrays.asList(types)));
         classDefs = this.getJpaTemplate().findByNamedQueryAndNamedParams(ClassDefinition.FIND_PARENT_ID_AND_TYPE, paras);
      }else {
         classDefs = this.getJpaTemplate().findByNamedQueryAndNamedParams(ClassDefinition.FIND_PARENT_ID, paras);
      }
      if (classDefs.size() > 0){
         return classDefs;
      }
      return null;
   }

   @SuppressWarnings("unchecked")
   public List<ClassDefinition> findOriginalClass(Long storageId) {
      Map<String, Object> paras = new HashMap<String, Object>();
      paras.put(ClassDefinition.ID_PARA, storageId);
      List<ClassDefinition> classDefs = this.getJpaTemplate().findByNamedQueryAndNamedParams(ClassDefinition.FIND_PARENT_ID_NULL, paras);
      if (classDefs.size() > 0){
         return classDefs;
      }
      return null;
   }

   @SuppressWarnings("unchecked")
   public ClassDefinition findUUID(Long storageId, String uuid) {
      Map<String, Object> paras = new HashMap<String, Object>();
      paras.put(ClassDefinition.UUID_PARA, uuid);
      paras.put(ClassDefinition.ID_PARA, storageId);
      List<ClassDefinition> classDefs = this.getJpaTemplate().findByNamedQueryAndNamedParams(ClassDefinition.FIND_UUID, paras);
      if (classDefs.size() > 0){
         return classDefs.get(0);
      }
      return null;
   }
}
